package com.nariano.webapp;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.rmi.server.UID;

import org.apache.wicket.Session;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxFallbackLink;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.image.Image;
import org.apache.wicket.markup.html.image.resource.DynamicImageResource;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.validation.IValidatable;
import org.apache.wicket.validation.validator.AbstractValidator;

import com.octo.captcha.service.image.DefaultManageableImageCaptchaService;
import com.octo.captcha.service.image.ImageCaptchaService;
import javax.imageio.ImageIO;

public class JCaptcha extends WebPage {
    
  private static final long serialVersionUID = 1L;

  private static final class CaptchaForm extends Form {

    private String challengeId = null;

    private String challengeResponse;

    public CaptchaForm(String id) {
      super(id);

      DynamicImageResource res = new DynamicImageResource() {
        @Override
        protected byte[] getImageData() {
          ByteArrayOutputStream os = new ByteArrayOutputStream();
          challengeId = new UID().toString();
          BufferedImage challenge = captchaService
              .getImageChallengeForID(challengeId, Session.get()
                  .getLocale());
          
          try {
              ImageIO.write(challenge, "png", os);
            return os.toByteArray();
          } catch (Exception e) {
            throw new RuntimeException(e);
          }
        }
      };
      final WebMarkupContainer wmc = new WebMarkupContainer("test");
      add(wmc);
      wmc.setOutputMarkupId(true);
      final Image image = new Image("captchaImage", res);
      image.setOutputMarkupId(true);
      wmc.add(image);

      add(new TextField("response", new PropertyModel(this,
          "challengeResponse")) {
        @Override
        protected final void onComponentTag(final ComponentTag tag) {
          super.onComponentTag(tag);
          tag.put("value", "");
        }
      }.setRequired(true).add(new AbstractValidator() {

        @Override
        protected void onValidate(IValidatable validatable) {
          if (!captchaService.validateResponseForID(challengeId,
              validatable.getValue())) {
            error(validatable);
          }
        }

        @Override
        protected String resourceKey() {
          return "captcha.validation.failed";
        }
      }));
      
      add(new AjaxFallbackLink("generateCaptcha") {

          @Override
          public void onClick(AjaxRequestTarget target) {
              if (target==null) {
                  setResponsePage(JCaptcha.class);
              } else {
                  target.addComponent(wmc);
              }
          }

            

        });


      add(new FeedbackPanel("feedback"));
    }

    public String getChallengeResponse() {
      return challengeResponse;
    }

    public void setChallengeResponse(String challengeResponse) {
      this.challengeResponse = challengeResponse;
    }

    @Override
    protected void onSubmit() {
      info(getLocalizer().getString("captcha.validation.succeeded",
          this));
    }
  }

  private static final ImageCaptchaService captchaService = new DefaultManageableImageCaptchaService();

  public JCaptcha() {
    add(new CaptchaForm("form"));
  }
}
